package responseModel

import (
	"encoding/xml"
	"fmt"
	"strings"
	"time"
)

// DataDeliveryResponse 对应根元素 dataDeliveryResponse
type DataDeliveryResponse struct {
	XMLName xml.Name `xml:"dataDeliveryResponse"`
	Sites   Site     `xml:"site"`
}

// Site 对应 site 元素
type Site struct {
	ID       string  `xml:"id,attr"`
	Lat      float64 `xml:"lat,attr"`
	Lng      float64 `xml:"lng,attr"`
	Metadata string  `xml:"metadata"`
	Columns  string  `xml:"columns"`
	Rows     []Row   `xml:"row"`
}

// Row 对应 row 元素
type Row struct {
	DateTime time.Time `xml:"dateTime,attr"`
	Values   string    `xml:"values,attr"`
}

// Measurement 解析后的数据结构
type Measurement struct {
	DateTime time.Time
	//	全球水平辐照 [kWh/m2、Wh/m2、W/m2]。
	GHI string
	//	晴空全球水平辐照 [kWh/m2， Wh/m2， W/m2]
	GHI_C string
	//	GHI 高估计值（超标概率 10%）[kWh/m2、Wh/m2、W/m2]
	GHI_UNC_HIGH string
	//	GHI 低估计值（超标概率 90%）[kWh/m2、Wh/m2、W/m2]
	GHI_UNC_LOW string
	//	直接法向辐照 [kWh/m2、Wh/m2、W/m2]
	DNI string
	//	晴空直接法向辐照 [kWh/m2， Wh/m2， W/m2]
	DNI_C string
	//	漫射水平辐照 [kWh/m2， Wh/m2， W/m2]
	DIF string
	//	全局倾斜辐照 [kWh/m2、Wh/m2、W/m2]
	GTI string
	//	GTI 高估计值（10% 的超标概率）[kWh/m2、Wh/m2、W/m2]
	GTI_UNC_HIGH string
	//	GTI 低估计值（90% 的超标概率）[kWh/m2、Wh/m2、W/m2]
	GTI_UNC_LOW string
	//	全局倾斜晴空辐照度 [W/m2]
	GTI_C string
	//	云识别质量标志 [类别]
	CI_FLAG string
	//	已弃用的 CI_FLAG 别名
	FLAG_R string
	//	KC 的已弃用别名。可以在未来的版本中停产。
	KTM string
	//	晴空索引 [无单位]
	KC string
	//	清净度指数，值范围 （0， 1.1），夜间 -9
	KT string
	//	光合主动辐照 [kWh/m2、Wh/m2、W/m2]
	PAR string
	//	太阳高度（仰角）角度 [度]
	SE string
	//	太阳方位角 [度]
	SA string
	//	2m [摄氏度] 时的空气温度
	TEMP string
	//	露点温度 [摄氏度]
	TD string
	//	湿球温度 [摄氏度]
	WBT string
	//	大气压力 [hPa]
	AP string
	//	相对湿度 [%]
	RH string
	//	风速 [m/s]
	WS string
	//	风向 [度]
	WD string
	//	降水率 [kg/m2]
	PREC string
	//	可降水 [kg/m2]
	PWAT string
	//	光伏输出 [kW，kWh]。关于单位，请参见下面的注释。
	PVOUT string
	//	PVOUT 高估计值（10 % 的超标概率）[kW，kWh]
	PVOUT_UNC_HIGH string
	//	PVOUT 低估计值（超标概率为 90%）[kW，kWh]
	PVOUT_UNC_LOW string
	//	积雪深度水当量 [kg/m2]
	SDWE string
	//	已弃用的 SDWE 别名。可以在未来的版本中停产。SDWE 将在响应中返回。
	SWE string
	//	模块温度 [摄氏度]。此参数需要在请求中定义一个光伏系统，至少在模拟设置中是这样：<pv：system installedPower=“1”><pv：module type=“CSI”/><pv：inverter/><pv：losses/></pv：system>
	TMOD string
	//	阵风 [m/s]
	WG string
	//	100 m 时的风速 [m/s]
	WS100 string
	//	风向 100 米 [度]
	WD100 string
	//	新降雪量的水当量 [kg/m2/小时] - 来源 ERA5 ，最新数据大约是倒退一个月（最近或预测期没有数据）
	SFWE string
	//	直接辐照度入射角[度]，此参数在请求中需要GTI或PVOUT
	INC string
	//	倾斜面倾斜度[度]，此参数在请求中需要GTI或PVOUT
	TILT string
	//	斜面方面[度]，此参数要求中需要GTI或PVOUT
	ASPECT string
}

func (s *Site) ParseMeasurements() ([]Measurement, error) {
	columns := strings.Split(s.Columns, " ")
	measurements := make([]Measurement, 0, len(s.Rows))

	for _, row := range s.Rows {
		values := strings.Split(row.Values, " ")
		if len(values) != len(columns) {
			continue // 跳过格式不正确的行
		}

		measurement := Measurement{
			DateTime: row.DateTime,
		}

		for i, col := range columns {
			switch col {
			case "GHI":
				fmt.Sscanf(values[i], "%f", &measurement.GHI)
			case "GHI_C":
				fmt.Sscanf(values[i], "%f", &measurement.GHI_C)
			case "GHI_UNC_HIGH":
				fmt.Sscanf(values[i], "%f", &measurement.GHI_UNC_HIGH)
			case "GHI_UNC_LOW":
				fmt.Sscanf(values[i], "%f", &measurement.GHI_UNC_LOW)
			case "DNI":
				fmt.Sscanf(values[i], "%f", &measurement.DNI)
			case "DNI_C":
				fmt.Sscanf(values[i], "%f", &measurement.DNI_C)
			case "DIF":
				fmt.Sscanf(values[i], "%f", &measurement.DIF)
			case "GTI":
				fmt.Sscanf(values[i], "%f", &measurement.GTI)
			case "GTI_UNC_HIGH":
				fmt.Sscanf(values[i], "%f", &measurement.GTI_UNC_HIGH)
			case "GTI_UNC_LOW":
				fmt.Sscanf(values[i], "%f", &measurement.GTI_UNC_LOW)
			case "GTI_C":
				fmt.Sscanf(values[i], "%f", &measurement.GTI_C)
			case "CI_FLAG":
				fmt.Sscanf(values[i], "%f", &measurement.CI_FLAG)
			case "FLAG_R":
				fmt.Sscanf(values[i], "%f", &measurement.FLAG_R)
			case "KTM":
				fmt.Sscanf(values[i], "%f", &measurement.KTM)
			case "KC":
				fmt.Sscanf(values[i], "%f", &measurement.KC)
			case "KT":
				fmt.Sscanf(values[i], "%f", &measurement.KT)
			case "PAR":
				fmt.Sscanf(values[i], "%f", &measurement.PAR)
			case "SE":
				fmt.Sscanf(values[i], "%f", &measurement.SE)
			case "SA":
				fmt.Sscanf(values[i], "%f", &measurement.SA)
			case "TEMP":
				fmt.Sscanf(values[i], "%f", &measurement.TEMP)
			case "TD":
				fmt.Sscanf(values[i], "%f", &measurement.TD)
			case "WBT":
				fmt.Sscanf(values[i], "%f", &measurement.WBT)
			case "AP":
				fmt.Sscanf(values[i], "%f", &measurement.AP)
			case "RH":
				fmt.Sscanf(values[i], "%f", &measurement.RH)
			case "WS":
				fmt.Sscanf(values[i], "%f", &measurement.WS)
			case "WD":
				fmt.Sscanf(values[i], "%f", &measurement.WD)
			case "PREC":
				fmt.Sscanf(values[i], "%f", &measurement.PREC)
			case "PWAT":
				fmt.Sscanf(values[i], "%f", &measurement.PWAT)
			case "PVOUT":
				fmt.Sscanf(values[i], "%f", &measurement.PVOUT)
			case "PVOUT_UNC_HIGH":
				fmt.Sscanf(values[i], "%f", &measurement.PVOUT_UNC_HIGH)
			case "PVOUT_UNC_LOW":
				fmt.Sscanf(values[i], "%f", &measurement.PVOUT_UNC_LOW)
			case "SDWE":
				fmt.Sscanf(values[i], "%f", &measurement.SDWE)
			case "SWE":
				fmt.Sscanf(values[i], "%f", &measurement.SWE)
			case "TMOD":
				fmt.Sscanf(values[i], "%f", &measurement.TMOD)
			case "WG":
				fmt.Sscanf(values[i], "%f", &measurement.WG)
			case "WS100":
				fmt.Sscanf(values[i], "%f", &measurement.WS100)
			case "WD100":
				fmt.Sscanf(values[i], "%f", &measurement.WD100)
			case "SFWE":
				fmt.Sscanf(values[i], "%f", &measurement.SFWE)
			case "INC":
				fmt.Sscanf(values[i], "%f", &measurement.INC)
			case "TILT":
				fmt.Sscanf(values[i], "%f", &measurement.TILT)
			case "ASPECT":
				fmt.Sscanf(values[i], "%f", &measurement.ASPECT)

			}
		}

		measurements = append(measurements, measurement)
	}

	return measurements, nil
}
